package com.powerbank.devicecenter.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.powerbank.devicecenter.entity.Device;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;

/**
 * 设备Mapper接口
 */
@Mapper
public interface DeviceMapper extends BaseMapper<Device> {

    /**
     * 根据设备编号查询设备
     */
    @Select("SELECT * FROM device WHERE device_code = #{deviceCode} AND deleted = 0")
    Device findByDeviceCode(@Param("deviceCode") String deviceCode);

    /**
     * 根据站点ID查询设备列表
     */
    @Select("SELECT * FROM device WHERE station_id = #{stationId} AND deleted = 0")
    List<Device> findByStationId(@Param("stationId") Long stationId);

    /**
     * 根据状态查询设备列表
     */
    @Select("SELECT * FROM device WHERE status = #{status} AND deleted = 0")
    List<Device> findByStatus(@Param("status") String status);

    /**
     * 查询可用设备列表
     */
    @Select("SELECT * FROM device WHERE status = 'AVAILABLE' AND enabled = 1 AND deleted = 0")
    List<Device> findAvailableDevices();

    /**
     * 根据位置范围查询设备
     */
    @Select("SELECT * FROM device WHERE " +
            "longitude BETWEEN #{minLng} AND #{maxLng} " +
            "AND latitude BETWEEN #{minLat} AND #{maxLat} " +
            "AND deleted = 0")
    List<Device> findByLocationRange(@Param("minLng") BigDecimal minLng,
                                   @Param("maxLng") BigDecimal maxLng,
                                   @Param("minLat") BigDecimal minLat,
                                   @Param("maxLat") BigDecimal maxLat);

    /**
     * 查询低电量设备
     */
    @Select("SELECT * FROM device WHERE battery_level < #{threshold} AND deleted = 0")
    List<Device> findLowBatteryDevices(@Param("threshold") Integer threshold);

    /**
     * 查询离线设备
     */
    @Select("SELECT * FROM device WHERE last_heartbeat < #{timeout} AND deleted = 0")
    List<Device> findOfflineDevices(@Param("timeout") LocalDateTime timeout);

    /**
     * 更新设备状态
     */
    @Update("UPDATE device SET status = #{status}, updated_time = NOW() WHERE id = #{deviceId}")
    int updateDeviceStatus(@Param("deviceId") Long deviceId, @Param("status") String status);

    /**
     * 更新设备电量
     */
    @Update("UPDATE device SET battery_level = #{batteryLevel}, charging_status = #{chargingStatus}, updated_time = NOW() WHERE id = #{deviceId}")
    int updateDeviceBattery(@Param("deviceId") Long deviceId, 
                           @Param("batteryLevel") Integer batteryLevel, 
                           @Param("chargingStatus") String chargingStatus);

    /**
     * 更新设备心跳
     */
    @Update("UPDATE device SET last_heartbeat = #{heartbeatTime}, last_online = #{heartbeatTime}, updated_time = NOW() WHERE device_code = #{deviceCode}")
    int updateDeviceHeartbeat(@Param("deviceCode") String deviceCode, @Param("heartbeatTime") LocalDateTime heartbeatTime);

    /**
     * 更新设备位置
     */
    @Update("UPDATE device SET longitude = #{longitude}, latitude = #{latitude}, address = #{address}, updated_time = NOW() WHERE id = #{deviceId}")
    int updateDeviceLocation(@Param("deviceId") Long deviceId, 
                            @Param("longitude") BigDecimal longitude, 
                            @Param("latitude") BigDecimal latitude, 
                            @Param("address") String address);

    /**
     * 增加设备使用次数
     */
    @Update("UPDATE device SET usage_count = usage_count + 1, total_usage_time = total_usage_time + #{usageTime}, updated_time = NOW() WHERE id = #{deviceId}")
    int incrementUsageCount(@Param("deviceId") Long deviceId, @Param("usageTime") Integer usageTime);

    /**
     * 统计站点设备数量
     */
    @Select("SELECT COUNT(*) FROM device WHERE station_id = #{stationId} AND deleted = 0")
    Integer countByStationId(@Param("stationId") Long stationId);

    /**
     * 统计各状态设备数量
     */
    @Select("SELECT status, COUNT(*) as count FROM device WHERE station_id = #{stationId} AND deleted = 0 GROUP BY status")
    List<Object> countByStatusAndStationId(@Param("stationId") Long stationId);
}